//
//  vdES1.m
//  Void Dead
//
//  Created by Sidney Just on 22.11.09.
//
//  Copyright © 2009 by Sidney Just
//  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
//  documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
//  the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 
//  and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
//  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
//  PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 
//  FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
//  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

#import "vdES1.h"


@implementation vdES1

- (BOOL)setupView {
	// Create the EAGLLayer and EAGLContext for OpenGL ES 1.1
	CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
	
	eaglLayer.opaque = YES;
	eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
									[NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
	
	context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
	
	if (!context || ![EAGLContext setCurrentContext:context]) {
		[self release];
		return NO;
	}
	
	return YES;
}

#pragma mark -
#pragma mark Buffer

- (BOOL)createFramebuffer {
    glGenFramebuffersOES(1, &viewFramebuffer);
    glGenRenderbuffersOES(1, &viewRenderbuffer);
	
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
	
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
	
    if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
        NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
        return NO;
    }
	
    return YES;
}

- (void)destroyFramebuffer {
	if(viewFramebuffer > 0)
	{
		glDeleteFramebuffersOES(1, &viewFramebuffer);
		viewFramebuffer = 0;
	}
	
	if(viewRenderbuffer > 0)
	{
		glDeleteRenderbuffersOES(1, &viewRenderbuffer);
		viewRenderbuffer = 0;
	}
}

- (void)layoutSubviews {
    [EAGLContext setCurrentContext:context];
    [self destroyFramebuffer];
    [self createFramebuffer];
	
	[self prepareRendering];
	[self completeRendering];
}

#pragma mark -
#pragma mark Rendering

- (void)applyOrientation {       
	int addY = 0;
	if(backingWidth > 480)
	{
		addY = 128;
	}
	
	int dim_x = backingWidth / 2;
	int dim_y = backingHeight / 2;
	
	switch(orientation) {
		case UIInterfaceOrientationPortrait:
			
			break;
		case UIInterfaceOrientationPortraitUpsideDown:
			glTranslatef(dim_x, dim_y, 0);
			glRotatef(180, 0, 0, 1);
			glTranslatef(-dim_x, -dim_y, 0);
			break;
		case UIInterfaceOrientationLandscapeLeft:
			glTranslatef(dim_x, dim_y, 0);
			glRotatef(90, 0, 0, 1);
			glTranslatef(-dim_y, -(dim_x*2)+addY, 0);
			break;
		case UIInterfaceOrientationLandscapeRight:
			glTranslatef(dim_x, dim_y, 0);
			glRotatef(-90, 0, 0, 1);
			glTranslatef(-dim_y, -(dim_x*2)+addY, 0);
			break;
	}       
}

- (void)prepareRendering {
	[EAGLContext setCurrentContext:context];
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
	
	// Setup projection
	glLoadIdentity();
	glViewport(0, 0, backingWidth, backingHeight);
	glMatrixMode(GL_PROJECTION);

	glLoadIdentity();
	glOrthof(0, backingWidth, 0, backingHeight, -1000.0f, 1000.0f);
	[self applyOrientation];
	
	glMatrixMode(GL_MODELVIEW);
	
	// Clear the screen
	glClearColor(clearColor->red, clearColor->green, clearColor->blue, 1.0);
	glClear(GL_COLOR_BUFFER_BIT);
	
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}

- (void)completeRendering {
	glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
}

- (void)bindFramebuffer {
	[EAGLContext setCurrentContext:context];
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
}


#pragma mark -
#pragma mark Con- Destructor

- (id)initWithFrame:(CGRect)frame {
	if(self = [super initWithFrame:frame])
	{
		viewFramebuffer = 0;
		viewRenderbuffer = 0;
		
		context = NULL;
		
		if(![self setupView])
		{
			[self release];
			return NULL;
		}
	}
	return self;
}

- (void)dealloc {
	if(viewRenderbuffer)
	{
		glDeleteFramebuffersOES(1, &viewRenderbuffer);
		viewRenderbuffer = 0;
	}
	
	if(viewRenderbuffer)
	{
		glDeleteRenderbuffersOES(1, &viewRenderbuffer);
		viewRenderbuffer = 0;
	}
	
	if([EAGLContext currentContext] == context) {
        [EAGLContext setCurrentContext:nil];
    }
    
    [context release]; 
	
	[super dealloc];
}

@end

